Agasthya Shenoy and Dustin Tingley

Introduction

Harvard University has over 10,000 websites associated with unique faculty members. Any number of these sites may contain embedded or hyperlinked video. In order to find these videos, we created a Python script to scrape the html code from each website and its subpages. We then parsed the code, searching for html tags indicitave of the presence of videos. Our results and further explanation of our methods are summarised below.


Methods

Defining ‘video content’

We defined video content as any video embedded within an <iframe> tag (used to embed videos in a webpage) or explicitly hyperlinked with an <a> tag. We did not include links to content creator user pages (e.g. ‘https://www.youtube.com/harvard’), only links that directly went to a video or video playlist. Using this definition, we found that videos mostly came from YouTube.com and Vimeo.com, while a few embedded videos used the Kaltura.com platform (see Results for a summary).

Aquiring faculty websites

Websites had been previously collected for the VPAL-R LINK project. Help in collection was provided by other entities at the University for the purpose of LINK.

Faculty websites were collected through 3 channels:

  1. an initial list of sites provided by Faculty Development & Diversity

  2. manually collected webpages done by VPAL-Research

  3. Harvard Open Scholar (Harvard web publishing platform)

We defined ‘faculty’ as anyone with the position ‘Lecturer’ and above - meaning that people like graduate students and teaching fellows, who may still have their own websites, were excluded from our analysis. We have not actively collected the websites for these people.

Scraping and Cleaning the data

Scraping

Once the websites were collected, we used a Python script, called a “crawler”, to download the raw html from each website, including website subpages (e.g. ‘https://scholar.harvard.edu/dtingley/’ AND ‘https://scholar.harvard.edu/dtingley/publications’, etc.) This data was stored in an Amazon Web Services S3 bucket, which we use for the LINK project. Each page is associated with a HUID and a checksum - a unique code created from the data contained in the website:

Example Data Structure (Website Collection)
person_id url checksum
40809295 https://scholar.harvard.edu/dtingley 1c20b7ba5e98adcd6e49ce345ae35042
40809295 https://scholar.harvard.edu/dtingley/contact_owner 91ef7d4b8de0e5bfcbe1270a3a5c61f2
40809295 https://scholar.harvard.edu/dtingley/publications/fast-cheap-and-imperfect-us-public-opinion-about-solar-geoengineering-0 bf020c95d094582f830ac6fc2382b9b3
40809295 https://scholar.harvard.edu/dtingley/publications/sparse-multilevel-regression-and-poststratification-smrp fce6f1ad2dfd465f548a4ba168482870
40809295 https://scholar.harvard.edu/dtingley/publications/effects-adaptive-learning-massive-open-online-course-learners%E2%80%99-skill 9d3d24ccc186bbcbdd276a727f2e3ec0
40809295 https://scholar.harvard.edu/dtingley/publications/effects-environmental-stressors-daily-governance 469b85a76149d1b25bb2b1940ce50ba4

We used the checksum to identify duplicates: because the checksum is created based on the raw content of a webpage, pages with identical checksums also have identical content - even if the urls are different. After identifying duplicate pages, we deleted them to avoid double counting videos. After the de-duplication process, we were left with 157,159 unique webpages.

Next, we used a Python package called Beautiful Soup to parse the raw html code. We first looked for embedded videos by searching for all instances of the <iframe> html tag that also contained the term “youtube”, “vimeo”, or “player”. Sometimes, <iframe> tags with “player” were actually embedded SoundCloud players, so “soundcloud” was an excluded term.

Once an embedded video was found, we incremented a “embedded_video” counter, and extracted an html snippet that contained the video, e.g:

<iframe allowfullscreen="allowfullscreen" frameborder="1" height="205" src="https://www.youtube.com/embed/mh65upNaAqM" width="400"></iframe>

We then used the same process to find hyperlinked videos, this time looking for <a> tags that contained the term “youtube” or “vimeo”. A separate “hyperlinked_video” counter was incremented each time we found a video on a page, and we extracted the html snippet associated with it as well:

<a href=\"https://www.youtube.com/watch?v=mh65upNaAqM" target=\"_blank\">online</a>

After this stage was complete, we added the embedded and hyperlinked counters to get the number of total videos, and stored the video counts and the html snippets in a .csv file:

Example Data Structure (Video Counts)
person_id url total_videos embedded_html hyperlinked_html
40809295 https://scholar.harvard.edu/dtingley/publications/what-makes-foreign-policy-teams-tick-explaining-variation-group-performance 0
40809295 https://scholar.harvard.edu/dtingley/publications/export/xml/374206 0
40809295 https://scholar.harvard.edu/dtingley/software/txtorg 0
40809295 https://scholar.harvard.edu/dtingley/publications/plain-text-transparency-acquisition-analysis-and-access-stages-computer 0
40809295 https://scholar.harvard.edu/dtingley/publications/computer-assisted-text-analysis-comparative-politics 0
40809295 https://scholar.harvard.edu/dtingley/publications/public-opposition-foreign-acquisitions-domestic-companiesevidence-united 0
Note:
In this case, Dustin did not have any videos on his website. If videos were present, the 'embedded_html' and 'hyperlinked_html' fields would be populated.

Cleaning

Finally, we merged the above data source with an exisiting data source of biographical information. This data source was also created for the LINK project, and contained information about faculty members’ school associations. During this merge, we lost 700 unique HUIDs from the data. Upon further investigation, it became clear that these 700 HUIDs were associated with non-faculty members (e.g. graduate students, former students, etc). These people were present in our original data because anyone with access to HarvadKey can create an OpenScholar website - even if they are not faculty members.

When doing a final pass at the extracted code, we noticed that many faculty websites include a footer designed by their respective schools. These footers often included a link to the school’s YouTube user page. These schools can be found below:

Institutional YouTube Channels
School YouTube Link in Footer
Harvard Graduate School of Education youtube.com/user/HarvardEducation
Harvard Law School youtube.com/user/HarvardLawSchool
Harvard Divinity School youtube.com/user/HarvardDivinity
Harvard Kennedy School youtube.com/user/HarvardKennedySchool
Harvard Chan School of Public Health youtube.com/user/HarvardPublicHealth
Harvard Extension School youtube.com/user/HarvardExtension
Harvard Graduate School of Design youtube.com/user/TheHarvardGSD

Any faculty member belonging to the above schools has a footer on their website directing to the school’s YouTube page. For this reason, these links were not included in the below analysis.


Results

Roughly 2% of faculty members across Harvard University have videos on their websites, which translates to 248 faculty members with a total of 1806 videos across 796 unique urls.

Click the tabs below to view the different analyses.

Types of Videos

Type of Video
hyperlinked embedded
YouTube 866 416
Vimeo 384 113
Kaltura - 27

Percent of Websites with Videos

By “number of websites”, we mean “number of unique urls”. This means that many urls can be associated with just one faculty member.


Number of Websites with Videos (Bar Chart)

By “number of websites”, we mean “number of unique urls”. This means that many urls can be associated with just one faculty member.


Number of Websites with Videos (Table)

School Total Number of Sites with Videos Number with Hyperlinks Number with Embeds
BUS 33 32 1
OPR 1 1 0
DIV 3 2 2
SEAS 118 70 53
RAD 1 1 0
SPH 30 22 11
EDU 10 10 0
DES 1 0 1
HSDM 2 2 0
KSG 119 61 61
FAS 418 294 155
LAW 20 20 0
Visiting Faculty/Postdoc 13 11 2
HMS 27 5 22
Note:
Some sites may have both hyperlinks AND embedded video, so the sum of the last 2 columns may be greater than the first.

Limitations and looking forward

Under counting

  • When looking for hyperlinked videos, we only looked for links to YouTube.com and Vimeo.com. This decision was made after seeing that these were the sources of the majority of the embedded videos. Although these are the two leading video platforms not just at Harvard, but on the internet in general, it is possible that some faculty members may have links to videos hosted on other, lesser known websites.

  • It is possible that we have under-counted videos from the Harvard Medical School. HMS faculty use the Harvard Catalyst platform to create their websites. As far as we have been able to ascertain, this platform does not allow faculty members to post videos. If this functionality does in fact exist, or if HMS faculty members have websites we were not able to collect, our total count may be off.

  • Our database of fqaculty websites may not be comprehensive - faculty members may have websites we do not know of. As the LINK project progresses, our database of faculty websites will improve.

  • There were at least two cases where we lost legitimate data when merging the scraped data set and the biographical data set. This was because someone else (possibly an assistant) had set up an OpenScholar site for a faculty member using their own HUID, rather than the faculty member’s. While we believe we caught all instances of this (2), it is possible we missed more.

Looking forward

We are currently in the process of crawling, scraping, and analyzing department and organization websites. Once that data is processed, we will generate another report.

LS0tCnRpdGxlOiAiVmlkZW9zIGluIEZhY3VsdHkgV2Vic2l0ZXMiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAzCiAgICB0b2NfZmxvYXQ6IHllcwotLS0KIyMjI0FnYXN0aHlhIFNoZW5veSBhbmQgRHVzdGluIFRpbmdsZXkKYGBge3IgbG9hZGxpYnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQpkYXRhIDwtIHJlYWQuY3N2KCdkYXRhL2luX3Byb2dyZXNzLmNzdicsc3RyaW5nc0FzRmFjdG9ycyA9IEYpCm5yb3coZGF0YSkKYGBgCgpgYGB7ciwgZWNobyA9IEZBTFNFfQojIHNjcnViIG91dCBiYWQgdXJscyAoZHVwbGljYXRlcykKYmFkX3VybHMgPC0gZGF0YVtkYXRhJHVybCAlbGlrZSUgIlxcPyIgJiBkYXRhJHRvdGFsX3ZpZGVvcyA+IDAsXQpkb250X2RlbGV0ZSA8LSBiYWRfdXJscyAlPiUgZ3JvdXBfYnkocGVyc29uX2lkKSAlPiUgCiAgc3VtbWFyaXNlKG5fbGlua3MgPSBuKCkpICU+JSAKICBzdWJzZXQobl9saW5rcyA8IDIpCmJhZF91cmxzIDwtIGJhZF91cmxzWyEoYmFkX3VybHMkcGVyc29uX2lkICVpbiUgZG9udF9kZWxldGUkcGVyc29uX2lkKSxdCmJhZF91cmxzIDwtIHJvd25hbWVzKGJhZF91cmxzW2JhZF91cmxzJHRvdGFsX3ZpZGVvcz4wLF0pCmNsZWFuZXJfZGF0YSA8LSBkYXRhWy1hcy5udW1lcmljKGJhZF91cmxzKSxdCgojIG1lcmdlIHdpdGggYmlvX2RhdGEgdG8gZ2V0IHNjaG9vbCBhZmZpbGlhdGlvbgpiaW9fZGF0YSA8LSByZWFkLmNzdignZGF0YS9QZXJzb25MaW5rc19CaW8uY3N2JyxzdHJpbmdzQXNGYWN0b3JzID0gRikKCndpdGhfc2Nob29sIDwtIG1lcmdlKGNsZWFuZXJfZGF0YSxiaW9fZGF0YVssYygyLDkpXSxieS54ID0gInBlcnNvbl9pZCIsYnkueSA9ICJpZCIpCndpdGhfc2Nob29sIDwtIGRpc3RpbmN0KHdpdGhfc2Nob29sKQp3aXRoX3NjaG9vbCRoeXBlcmxpbmtlZF9odG1sIDwtIGdzdWIoIlxcW10iLCIiLHdpdGhfc2Nob29sJGh5cGVybGlua2VkX2h0bWwpCndpdGhfc2Nob29sJGVtYmVkZGVkX2h0bWwgPC0gZ3N1YigiXFxbXSIsIiIsd2l0aF9zY2hvb2wkZW1iZWRkZWRfaHRtbCkKCnJlbW92ZV9mb290ZXJzIDwtIGZ1bmN0aW9uKHgpewogIGxpbmtzIDwtIHN0cnNwbGl0KHgsIj4sIilbWzFdXQogIAogIGxpbmtzIDwtIGxpbmtzICU+JSAgbGFwcGx5KGZ1bmN0aW9uKHgpIHBhc3RlKHgsIj4iLHNlcD0iIikpCiAgCiAgbGlua3MgPC0gdW5saXN0KGxpbmtzKQogIGZvdW5kIDwtIGdyZXAoIkhhcnZhcmRFZHVjYXRpb258SGFydmFyZExhd1NjaG9vbHxIYXJ2YXJkRGl2aW5pdHl8SGFydmFyZEtlbm5lZHlTY2hvb2x8SGFydmFyZFB1YmxpY0hlYWx0aHxIYXJ2YXJkRXh0ZW5zaW9ufFRoZUhhcnZhcmRHU0QiLGxpbmtzKQogIAogIGlmKGxlbmd0aChmb3VuZCk+MCl7CiAgICBsaW5rcyA8LSBsaW5rc1stZm91bmRdCiAgfQogIGxpbmtzIDwtIHBhc3RlKGxpbmtzLGNvbGxhcHNlPSIsIikKICB1bmxpc3QobGlua3MpCn0KCnNwbGl0X2h0bWwgPC0gZnVuY3Rpb24oeCl7CiAgc3Ryc3BsaXQoeCwiPiwiKVtbMV1dCn0KCmNvdW50X2h0bWwgPC0gZnVuY3Rpb24oeCl7CiAgbGVuZ3RoKHNwbGl0X2h0bWwoeCkpCn0KCiMgd2l0aF9zY2hvb2wkaHlwZXJsaW5rZWRfaHRtbCA8LSBsYXBwbHkod2l0aF9zY2hvb2wkaHlwZXJsaW5rZWRfaHRtbCxyZW1vdmVfZm9vdGVycykKCnJlYWxfbnVtX2h0bWwgPC0gbGFwcGx5KHdpdGhfc2Nob29sJGh5cGVybGlua2VkX2h0bWwsY291bnRfaHRtbCkKd2l0aF9zY2hvb2wkcmVhbF9udW1faHRtbCA8LSB1bmxpc3QocmVhbF9udW1faHRtbCkKd2l0aF9zY2hvb2wkcmVhbF90b3RhbCA8LSB3aXRoX3NjaG9vbCRudW1fZW1iZWRkZWQgKyB3aXRoX3NjaG9vbCRyZWFsX251bV9odG1sCgp3cml0ZS5jc3Yod2l0aF9zY2hvb2wsImZhY3VsdHlfa2FsdHVyYV9wcmUuY3N2IikKYGBgCgojSW50cm9kdWN0aW9uCgpIYXJ2YXJkIFVuaXZlcnNpdHkgaGFzIG92ZXIgMTAsMDAwIHdlYnNpdGVzIGFzc29jaWF0ZWQgd2l0aCB1bmlxdWUgZmFjdWx0eSBtZW1iZXJzLiBBbnkgbnVtYmVyIG9mIHRoZXNlIHNpdGVzIG1heSBjb250YWluIGVtYmVkZGVkIG9yIGh5cGVybGlua2VkIHZpZGVvLiBJbiBvcmRlciB0byBmaW5kIHRoZXNlIHZpZGVvcywgd2UgY3JlYXRlZCBhIFB5dGhvbiBzY3JpcHQgdG8gc2NyYXBlIHRoZSBodG1sIGNvZGUgZnJvbSBlYWNoIHdlYnNpdGUgYW5kIGl0cyBzdWJwYWdlcy4gV2UgdGhlbiBwYXJzZWQgdGhlIGNvZGUsIHNlYXJjaGluZyBmb3IgaHRtbCB0YWdzIGluZGljaXRhdmUgb2YgdGhlIHByZXNlbmNlIG9mIHZpZGVvcy4gT3VyIHJlc3VsdHMgYW5kIGZ1cnRoZXIgZXhwbGFuYXRpb24gb2Ygb3VyIG1ldGhvZHMgYXJlIHN1bW1hcmlzZWQgYmVsb3cuCgotLS0KCiNNZXRob2RzCgojIyNEZWZpbmluZyAndmlkZW8gY29udGVudCcKCldlIGRlZmluZWQgdmlkZW8gY29udGVudCBhcyBhbnkgdmlkZW8gZW1iZWRkZWQgd2l0aGluIGFuIGA8aWZyYW1lPmAgdGFnICh1c2VkIHRvIGVtYmVkIHZpZGVvcyBpbiBhIHdlYnBhZ2UpIG9yIGV4cGxpY2l0bHkgaHlwZXJsaW5rZWQgd2l0aCBhbiBgPGE+YCB0YWcuIFdlIGRpZCBub3QgaW5jbHVkZSBsaW5rcyB0byBjb250ZW50IGNyZWF0b3IgKnVzZXIgcGFnZXMqIChlLmcuICdodHRwczovL3d3dy55b3V0dWJlLmNvbS9oYXJ2YXJkJyksIG9ubHkgbGlua3MgdGhhdCBkaXJlY3RseSB3ZW50IHRvIGEgdmlkZW8gb3IgdmlkZW8gcGxheWxpc3QuIFVzaW5nIHRoaXMgZGVmaW5pdGlvbiwgd2UgZm91bmQgdGhhdCB2aWRlb3MgbW9zdGx5IGNhbWUgZnJvbSBZb3VUdWJlLmNvbSBhbmQgVmltZW8uY29tLCB3aGlsZSBhIGZldyBlbWJlZGRlZCB2aWRlb3MgdXNlZCB0aGUgS2FsdHVyYS5jb20gcGxhdGZvcm0gKHNlZSBbUmVzdWx0c10oI1Jlc3VsdHMpIGZvciBhIHN1bW1hcnkpLgoKYGBge3IsIGVjaG89RkFMU0V9CgojIGh5cGVybGlua2VkCmFsbHVybHNfaHlwIDwtIGxhcHBseSh3aXRoX3NjaG9vbCRoeXBlcmxpbmtlZF9odG1sLHNwbGl0X2h0bWwpCmFsbHVybHNfaHlwIDwtIHVubGlzdChhbGx1cmxzX2h5cCkKeXRfaHlwIDwtIGxlbmd0aChncmVwKCJ5b3V0dWJlLmNvbSIsYWxsdXJsc19oeXApKQp2aW1lb19oeXAgPC0gbGVuZ3RoKGdyZXAoInZpbWVvLmNvbSIsYWxsdXJsc19oeXApKQoKI2VtYmVkZGVkCmFsbHVybHNfZW1iIDwtIGxhcHBseSh3aXRoX3NjaG9vbCRlbWJlZGRlZF9odG1sLHNwbGl0X2h0bWwpCmFsbHVybHNfZW1iIDwtIHVubGlzdChhbGx1cmxzX2VtYikKCnl0X2VtYiA8LSBsZW5ndGgoZ3JlcCgieW91dHViZS5jb20iLGFsbHVybHNfZW1iKSkKdmltZW9fZW1iIDwtIGxlbmd0aChncmVwKCJ2aW1lby5jb20iLGFsbHVybHNfZW1iKSkKCmJvdGhfeXR2aW0gPC0gZ3JlcCgieW91dHViZS5jb218dmltZW8uY29tIixhbGx1cmxzX2VtYikKbm9ueXQgPC0gYWxsdXJsc19lbWJbLWJvdGhfeXR2aW1dCm5vbnl0IDwtIGxlbmd0aChub255dFtub255dCAhPSAiIl0pCgp2aWRfc291cmNlcyA8LSBkYXRhLmZyYW1lKGh5cGVybGlua2VkID0gYyh5dF9oeXAsdmltZW9faHlwLCAiLSIpLGVtYmVkZGVkPWMoeXRfZW1iLHZpbWVvX2VtYixub255dCkpCnJvd25hbWVzKHZpZF9zb3VyY2VzKSA8LSBjKCJZb3VUdWJlIiwiVmltZW8iLCJLYWx0dXJhIikgCmBgYAoKIyMjQXF1aXJpbmcgZmFjdWx0eSB3ZWJzaXRlcwoKV2Vic2l0ZXMgaGFkIGJlZW4gcHJldmlvdXNseSBjb2xsZWN0ZWQgZm9yIHRoZSBbVlBBTC1SIExJTktdKGh0dHBzOi8vc2l0ZXMuZ29vZ2xlLmNvbS92aWV3L2ZhY3VsdHlsaW5rKSBwcm9qZWN0LiBIZWxwIGluIGNvbGxlY3Rpb24gd2FzIHByb3ZpZGVkIGJ5IG90aGVyIGVudGl0aWVzIGF0IHRoZSBVbml2ZXJzaXR5IGZvciB0aGUgcHVycG9zZSBvZiBMSU5LLiAKCkZhY3VsdHkgd2Vic2l0ZXMgd2VyZSBjb2xsZWN0ZWQgdGhyb3VnaCAzIGNoYW5uZWxzOiAKCigxKSBhbiBpbml0aWFsIGxpc3Qgb2Ygc2l0ZXMgcHJvdmlkZWQgYnkgRmFjdWx0eSBEZXZlbG9wbWVudCAmIERpdmVyc2l0eQoKKDIpIG1hbnVhbGx5IGNvbGxlY3RlZCB3ZWJwYWdlcyBkb25lIGJ5IFZQQUwtUmVzZWFyY2gKCigzKSBIYXJ2YXJkIE9wZW4gU2Nob2xhciAoSGFydmFyZCB3ZWIgcHVibGlzaGluZyBwbGF0Zm9ybSkKCldlIGRlZmluZWQgJ2ZhY3VsdHknIGFzIGFueW9uZSB3aXRoIHRoZSBwb3NpdGlvbiAnTGVjdHVyZXInIGFuZCBhYm92ZSAtIG1lYW5pbmcgdGhhdCBwZW9wbGUgbGlrZSBncmFkdWF0ZSBzdHVkZW50cyBhbmQgdGVhY2hpbmcgZmVsbG93cywgd2hvIG1heSBzdGlsbCBoYXZlIHRoZWlyIG93biB3ZWJzaXRlcywgd2VyZSBleGNsdWRlZCBmcm9tIG91ciBhbmFseXNpcy4gV2UgaGF2ZSBub3QgYWN0aXZlbHkgY29sbGVjdGVkIHRoZSB3ZWJzaXRlcyBmb3IgdGhlc2UgcGVvcGxlLgoKIyMjU2NyYXBpbmcgYW5kIENsZWFuaW5nIHRoZSBkYXRhCgojIyMjU2NyYXBpbmcKT25jZSB0aGUgd2Vic2l0ZXMgd2VyZSBjb2xsZWN0ZWQsIHdlIHVzZWQgYSBQeXRob24gc2NyaXB0LCBjYWxsZWQgYSAiY3Jhd2xlciIsIHRvIGRvd25sb2FkIHRoZSByYXcgaHRtbCBmcm9tIGVhY2ggd2Vic2l0ZSwgaW5jbHVkaW5nIHdlYnNpdGUgc3VicGFnZXMgKGUuZy4gJ2h0dHBzOi8vc2Nob2xhci5oYXJ2YXJkLmVkdS9kdGluZ2xleS8nIEFORCAnaHR0cHM6Ly9zY2hvbGFyLmhhcnZhcmQuZWR1L2R0aW5nbGV5L3B1YmxpY2F0aW9ucycsIGV0Yy4pIFRoaXMgZGF0YSB3YXMgc3RvcmVkIGluIGFuIEFtYXpvbiBXZWIgU2VydmljZXMgUzMgYnVja2V0LCB3aGljaCB3ZSB1c2UgZm9yIHRoZSBMSU5LIHByb2plY3QuIEVhY2ggcGFnZSBpcyBhc3NvY2lhdGVkIHdpdGggYSBIVUlEIGFuZCBhIGNoZWNrc3VtIC0gYSB1bmlxdWUgY29kZSBjcmVhdGVkIGZyb20gdGhlIGRhdGEgY29udGFpbmVkIGluIHRoZSB3ZWJzaXRlOgoKYGBge3IsIGVjaG89RkFMU0V9CnBlcnNvbnJlc291cmNlIDwtIHJlYWQuY3N2KCdkYXRhL3BlcnNvbl9yZXNvdXJjZS5jc3YnLHN0cmluZ3NBc0ZhY3RvcnMgPSBGKQpkdGluZyA8LSBoZWFkKHBlcnNvbnJlc291cmNlW2dyZXAoImR0aW5nbGV5IixwZXJzb25yZXNvdXJjZSR1cmwpLC1jKDEsMyw1KV0pCgprYWJsZShkdGluZywgcm93Lm5hbWVzID0gRkFMU0UpICU+JSBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIpKSAlPiUgCiAgYWRkX2hlYWRlcl9hYm92ZShjKCJFeGFtcGxlIERhdGEgU3RydWN0dXJlIChXZWJzaXRlIENvbGxlY3Rpb24pIj0zKSx1bmRlcmxpbmUgPSBUUlVFKQpgYGAKV2UgdXNlZCB0aGUgY2hlY2tzdW0gdG8gaWRlbnRpZnkgZHVwbGljYXRlczogYmVjYXVzZSB0aGUgY2hlY2tzdW0gaXMgY3JlYXRlZCBiYXNlZCBvbiB0aGUgcmF3IGNvbnRlbnQgb2YgYSB3ZWJwYWdlLCBwYWdlcyB3aXRoIGlkZW50aWNhbCBjaGVja3N1bXMgYWxzbyBoYXZlIGlkZW50aWNhbCBjb250ZW50IC0gZXZlbiBpZiB0aGUgdXJscyBhcmUgZGlmZmVyZW50LiBBZnRlciBpZGVudGlmeWluZyBkdXBsaWNhdGUgcGFnZXMsIHdlIGRlbGV0ZWQgdGhlbSB0byBhdm9pZCBkb3VibGUgY291bnRpbmcgdmlkZW9zLiBBZnRlciB0aGUgZGUtZHVwbGljYXRpb24gcHJvY2Vzcywgd2Ugd2VyZSBsZWZ0IHdpdGggKioxNTcsMTU5KiogdW5pcXVlIHdlYnBhZ2VzLgoKTmV4dCwgd2UgdXNlZCBhIFB5dGhvbiBwYWNrYWdlIGNhbGxlZCBbQmVhdXRpZnVsIFNvdXBdKGh0dHBzOi8vd3d3LmNydW1teS5jb20vc29mdHdhcmUvQmVhdXRpZnVsU291cC9iczQvZG9jLykgdG8gcGFyc2UgdGhlIHJhdyBodG1sIGNvZGUuIFdlIGZpcnN0IGxvb2tlZCBmb3IgZW1iZWRkZWQgdmlkZW9zIGJ5IHNlYXJjaGluZyBmb3IgYWxsIGluc3RhbmNlcyBvZiB0aGUgYDxpZnJhbWU+YCBodG1sIHRhZyB0aGF0IGFsc28gY29udGFpbmVkIHRoZSB0ZXJtICJ5b3V0dWJlIiwgInZpbWVvIiwgb3IgInBsYXllciIuIFNvbWV0aW1lcywgYDxpZnJhbWU+YCB0YWdzIHdpdGggInBsYXllciIgd2VyZSBhY3R1YWxseSBlbWJlZGRlZCBTb3VuZENsb3VkIHBsYXllcnMsIHNvICJzb3VuZGNsb3VkIiB3YXMgYW4gZXhjbHVkZWQgdGVybS4KCk9uY2UgYW4gZW1iZWRkZWQgdmlkZW8gd2FzIGZvdW5kLCB3ZSBpbmNyZW1lbnRlZCBhICJlbWJlZGRlZF92aWRlbyIgY291bnRlciwgYW5kIGV4dHJhY3RlZCBhbiBodG1sIHNuaXBwZXQgdGhhdCBjb250YWluZWQgdGhlIHZpZGVvLCBlLmc6CgpgPGlmcmFtZSBhbGxvd2Z1bGxzY3JlZW49ImFsbG93ZnVsbHNjcmVlbiIgZnJhbWVib3JkZXI9IjEiIGhlaWdodD0iMjA1ImAgCmBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL21oNjV1cE5hQXFNIiB3aWR0aD0iNDAwIj48L2lmcmFtZT5gCgpXZSB0aGVuIHVzZWQgdGhlIHNhbWUgcHJvY2VzcyB0byBmaW5kIGh5cGVybGlua2VkIHZpZGVvcywgdGhpcyB0aW1lIGxvb2tpbmcgZm9yIGA8YT5gIHRhZ3MgdGhhdCBjb250YWluZWQgdGhlIHRlcm0gInlvdXR1YmUiIG9yICJ2aW1lbyIuIEEgc2VwYXJhdGUgImh5cGVybGlua2VkX3ZpZGVvIiBjb3VudGVyIHdhcyBpbmNyZW1lbnRlZCBlYWNoIHRpbWUgd2UgZm91bmQgYSB2aWRlbyBvbiBhIHBhZ2UsIGFuZCB3ZSBleHRyYWN0ZWQgdGhlIGh0bWwgc25pcHBldCBhc3NvY2lhdGVkIHdpdGggaXQgYXMgd2VsbDoKCmA8YSBocmVmPVwiaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1taDY1dXBOYUFxTSIgdGFyZ2V0PVwiX2JsYW5rXCI+b25saW5lPC9hPmAKCkFmdGVyIHRoaXMgc3RhZ2Ugd2FzIGNvbXBsZXRlLCB3ZSBhZGRlZCB0aGUgZW1iZWRkZWQgYW5kIGh5cGVybGlua2VkIGNvdW50ZXJzIHRvIGdldCB0aGUgbnVtYmVyIG9mIHRvdGFsIHZpZGVvcywgYW5kIHN0b3JlZCB0aGUgdmlkZW8gY291bnRzIGFuZCB0aGUgaHRtbCBzbmlwcGV0cyBpbiBhIC5jc3YgZmlsZToKCmBgYHtyLCBlY2hvPUZBTFNFfQpkdHJlc3VsdHMgPC0gaGVhZCh3aXRoX3NjaG9vbFtncmVwKCJkdGluZ2xleSIsd2l0aF9zY2hvb2wkdXJsKSwtYyg0LDYsOCw5LDEwKV0pCmthYmxlKGR0cmVzdWx0cyxyb3cubmFtZXMgPSBGQUxTRSkgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIikpICU+JSAKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIkV4YW1wbGUgRGF0YSBTdHJ1Y3R1cmUgKFZpZGVvIENvdW50cykiPTUpLHVuZGVybGluZSA9IFRSVUUpICU+JSAKICBmb290bm90ZShnZW5lcmFsID0gIkluIHRoaXMgY2FzZSwgRHVzdGluIGRpZCBub3QgaGF2ZSBhbnkgdmlkZW9zIG9uIGhpcyB3ZWJzaXRlLiBJZiB2aWRlb3Mgd2VyZSBwcmVzZW50LCB0aGUgJ2VtYmVkZGVkX2h0bWwnIGFuZCAnaHlwZXJsaW5rZWRfaHRtbCcgZmllbGRzIHdvdWxkIGJlIHBvcHVsYXRlZC4iKQpgYGAKCiMjIyNDbGVhbmluZwoKRmluYWxseSwgd2UgbWVyZ2VkIHRoZSBhYm92ZSBkYXRhIHNvdXJjZSB3aXRoIGFuIGV4aXNpdGluZyBkYXRhIHNvdXJjZSBvZiBiaW9ncmFwaGljYWwgaW5mb3JtYXRpb24uIFRoaXMgZGF0YSBzb3VyY2Ugd2FzIGFsc28gY3JlYXRlZCBmb3IgdGhlIExJTksgcHJvamVjdCwgYW5kIGNvbnRhaW5lZCBpbmZvcm1hdGlvbiBhYm91dCBmYWN1bHR5IG1lbWJlcnMnIHNjaG9vbCBhc3NvY2lhdGlvbnMuIER1cmluZyB0aGlzIG1lcmdlLCB3ZSBsb3N0IDcwMCB1bmlxdWUgSFVJRHMgZnJvbSB0aGUgZGF0YS4gVXBvbiBmdXJ0aGVyIGludmVzdGlnYXRpb24sIGl0IGJlY2FtZSBjbGVhciB0aGF0IHRoZXNlIDcwMCBIVUlEcyB3ZXJlIGFzc29jaWF0ZWQgd2l0aCBub24tZmFjdWx0eSBtZW1iZXJzIChlLmcuIGdyYWR1YXRlIHN0dWRlbnRzLCBmb3JtZXIgc3R1ZGVudHMsIGV0YykuIFRoZXNlIHBlb3BsZSB3ZXJlIHByZXNlbnQgaW4gb3VyIG9yaWdpbmFsIGRhdGEgYmVjYXVzZSBhbnlvbmUgd2l0aCBhY2Nlc3MgdG8gSGFydmFkS2V5IGNhbiBjcmVhdGUgYW4gT3BlblNjaG9sYXIgd2Vic2l0ZSAtIGV2ZW4gaWYgdGhleSBhcmUgbm90IGZhY3VsdHkgbWVtYmVycy4KCldoZW4gZG9pbmcgYSBmaW5hbCBwYXNzIGF0IHRoZSBleHRyYWN0ZWQgY29kZSwgd2Ugbm90aWNlZCB0aGF0IG1hbnkgZmFjdWx0eSB3ZWJzaXRlcyBpbmNsdWRlIGEgZm9vdGVyIGRlc2lnbmVkIGJ5IHRoZWlyIHJlc3BlY3RpdmUgc2Nob29scy4gVGhlc2UgZm9vdGVycyBvZnRlbiBpbmNsdWRlZCBhIGxpbmsgdG8gdGhlICpzY2hvb2wncyogWW91VHViZSB1c2VyIHBhZ2UuIFRoZXNlIHNjaG9vbHMgY2FuIGJlIGZvdW5kIGJlbG93OgoKYGBge3IsIGVjaG89RkFMU0V9Cmluc3RfeXRsaW5rcyA8LSBjKCJIYXJ2YXJkRWR1Y2F0aW9uIiwKIkhhcnZhcmRMYXdTY2hvb2wiLAoiSGFydmFyZERpdmluaXR5IiwKIkhhcnZhcmRLZW5uZWR5U2Nob29sIiwKIkhhcnZhcmRQdWJsaWNIZWFsdGgiLAoiSGFydmFyZEV4dGVuc2lvbiIsCiJUaGVIYXJ2YXJkR1NEIikKCmluc3RfbmFtZXMgPC0gYygiSGFydmFyZCBHcmFkdWF0ZSBTY2hvb2wgb2YgRWR1Y2F0aW9uIiwgIkhhcnZhcmQgTGF3IFNjaG9vbCIsICJIYXJ2YXJkIERpdmluaXR5IFNjaG9vbCIsCiAgICAgICAgICAgICAgICAiSGFydmFyZCBLZW5uZWR5IFNjaG9vbCIsICJIYXJ2YXJkIENoYW4gU2Nob29sIG9mIFB1YmxpYyBIZWFsdGgiLAogICAgICAgICAgICAgICAgIkhhcnZhcmQgRXh0ZW5zaW9uIFNjaG9vbCIsIkhhcnZhcmQgR3JhZHVhdGUgU2Nob29sIG9mIERlc2lnbiIpCgppbnN0X3l0bGlua3MgPC0gaW5zdF95dGxpbmtzICU+JSBzYXBwbHkoRlVOPWZ1bmN0aW9uKHgpe3Bhc3RlKCd5b3V0dWJlLmNvbS91c2VyLycseCxzZXA9IiIpfSkKaW5zdF95dGxpbmtzIDwtIHVubGlzdChpbnN0X3l0bGlua3MpCgppbnN0aXR1dGlvbnMgPC0gZGF0YS5mcmFtZShpbnN0X3l0bGlua3MpCnJvd25hbWVzKGluc3RpdHV0aW9ucykgPC0gaW5zdF9uYW1lcwoKaW5zdGl0dXRpb25zIDwtIGluc3RpdHV0aW9ucyAlPiUgbXV0YXRlKAogIGluc3RfeXRsaW5rcyA9IHRleHRfc3BlYyhpbnN0X3l0bGlua3MsIGxpbmsgPSBpbnN0X3l0bGlua3MpLAogIHNjaG9vbCA9IHJvdy5uYW1lcyguKQopCmluc3RpdHV0aW9ucyA8LSBpbnN0aXR1dGlvbnNbLGMoMiwxKV0KbmFtZXMoaW5zdGl0dXRpb25zKSA8LSBjKCJTY2hvb2wiLCJZb3VUdWJlIExpbmsgaW4gRm9vdGVyIikKYGBgCgpgYGB7ciwgZWNobyA9IEZBTFNFfQprYWJsZShpbnN0aXR1dGlvbnMsIGVzY2FwZT1GKSAlPiUgCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIpLGZ1bGxfd2lkdGggPSBGLHBvc2l0aW9uPSJjZW50ZXIiKSAlPiUgCiAgYWRkX2hlYWRlcl9hYm92ZShjKCJJbnN0aXR1dGlvbmFsIFlvdVR1YmUgQ2hhbm5lbHMiID0gMiksdW5kZXJsaW5lPVRSVUUpCmBgYApBbnkgZmFjdWx0eSBtZW1iZXIgYmVsb25naW5nIHRvIHRoZSBhYm92ZSBzY2hvb2xzIGhhcyBhIGZvb3RlciBvbiB0aGVpciB3ZWJzaXRlIGRpcmVjdGluZyB0byB0aGUgc2Nob29sJ3MgWW91VHViZSBwYWdlLiBGb3IgdGhpcyByZWFzb24sIHRoZXNlIGxpbmtzICoqd2VyZSBub3QgaW5jbHVkZWQqKiBpbiB0aGUgYmVsb3cgYW5hbHlzaXMuCgotLS0KCjxhIG5hbWU9IlJlc3VsdHMiPjwvYT4KCiNSZXN1bHRzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfSAgCgoKIyMjI1JvdWdobHkgKioyJSoqIG9mIGZhY3VsdHkgbWVtYmVycyBhY3Jvc3MgSGFydmFyZCBVbml2ZXJzaXR5IGhhdmUgdmlkZW9zIG9uIHRoZWlyIHdlYnNpdGVzLCB3aGljaCB0cmFuc2xhdGVzIHRvICoqMjQ4KiogZmFjdWx0eSBtZW1iZXJzIHdpdGggYSB0b3RhbCBvZiAqKjE4MDYqKiB2aWRlb3MgYWNyb3NzICoqNzk2KiogdW5pcXVlIHVybHMuIAoKQ2xpY2sgdGhlIHRhYnMgYmVsb3cgdG8gdmlldyB0aGUgZGlmZmVyZW50IGFuYWx5c2VzLiAKCiMjVHlwZXMgb2YgVmlkZW9zCgpgYGB7ciwgZWNobz1GQUxTRX0Ka2FibGUodmlkX3NvdXJjZXMpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsImhvdmVyIiksZnVsbF93aWR0aCA9IEYscG9zaXRpb249ImNlbnRlciIpICU+JSAKICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMSwgIlR5cGUgb2YgVmlkZW8iID0gMikpCmBgYAoKCmBgYHtyLCBlY2hvPUZBTFNFfQpmb3Jfc3VtIDwtIHdpdGhfc2Nob29sICU+JSAKICBtdXRhdGUoaGFzX3ZpZCA9IGNhc2Vfd2hlbigKICAgIHJlYWxfdG90YWwgPiAwIH4gMSwKICAgIFRSVUUgfiAwCiAgKSwKICBoeXBlcl92aWQgPSBjYXNlX3doZW4oCiAgICBudW1faHlwZXJsaW5rZWQgPiAwIH4gMSwKICAgIFRSVUUgfiAwCiAgKSwKICBlbWJlZF92aWQgPSBjYXNlX3doZW4oCiAgICBudW1fZW1iZWRkZWQgPiAwIH4gMSwKICAgIFRSVUUgfiAwCiAgKSkgJT4lIGdyb3VwX2J5KHNjaG9vbF9maW5hbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3RvdGFsID0gbWVhbihoYXNfdmlkKSoxMDAsCiAgICAgICAgICAgIG5fdXJscyA9IHN1bShoYXNfdmlkKSwKICAgICAgICAgICAgbWVhbl9oeXBlciA9IG1lYW4oaHlwZXJfdmlkKSoxMDAsCiAgICAgICAgICAgIG5faHlwZXIgPSBzdW0oaHlwZXJfdmlkKSwKICAgICAgICAgICAgbWVhbl9lbWJlZCA9IG1lYW4oZW1iZWRfdmlkKSoxMDAsCiAgICAgICAgICAgIG5fZW1iZWQgPSBzdW0oZW1iZWRfdmlkKSkKCmZvcl9zdW0kc2Nob29sX2ZpbmFsWzFdIDwtICJWaXNpdGluZyBGYWN1bHR5L1Bvc3Rkb2MiCmZvcl9zdW0gPC0gZm9yX3N1bVtvcmRlcigtZm9yX3N1bSRtZWFuX3RvdGFsKSxdCgp4IDwtIGxpc3QoCiAgdGl0bGUgPSAiU2Nob29sIgopCnkgPC0gbGlzdCgKICB0aXRsZSA9ICJQZXJjZW50IG9mIFdlYnNpdGVzIHdpdGggVmlkZW9zIgopCgp5MiA8LSBsaXN0KAogIHRpdGxlID0gIk51bWJlciBvZiBXZWJzaXRlcyB3aXRoIFZpZGVvcyIKKQoKYGBgCgotLS0KCiMjUGVyY2VudCBvZiBXZWJzaXRlcyB3aXRoIFZpZGVvcwoKQnkgIm51bWJlciBvZiB3ZWJzaXRlcyIsIHdlIG1lYW4gIm51bWJlciBvZiB1bmlxdWUgdXJscyIuIFRoaXMgbWVhbnMgdGhhdCBtYW55IHVybHMgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCBqdXN0IG9uZSBmYWN1bHR5IG1lbWJlci4KYGBge3IsIGVjaG89RkFMU0V9CnBsb3RfbHkoZm9yX3N1bSx4PX5zY2hvb2xfZmluYWwseT1+bWVhbl90b3RhbCx0eXBlPSJiYXIiLGhvdmVydGV4dD1wYXN0ZSgiQWN0dWFsIE51bWJlciBvZiBTaXRlczoiLCBmb3Jfc3VtJG5fdXJscykseGF4aXM9IlNjaG9vbCIsIHdpZHRoPSAxMDAwLCBoZWlnaHQgPSA1MDApICU+JSAKICBsYXlvdXQoeGF4aXM9eCx5YXhpcz15KQpgYGAKCi0tLQoKIyNOdW1iZXIgb2YgV2Vic2l0ZXMgd2l0aCBWaWRlb3MgKEJhciBDaGFydCkKCkJ5ICJudW1iZXIgb2Ygd2Vic2l0ZXMiLCB3ZSBtZWFuICJudW1iZXIgb2YgdW5pcXVlIHVybHMiLiBUaGlzIG1lYW5zIHRoYXQgbWFueSB1cmxzIGNhbiBiZSBhc3NvY2lhdGVkIHdpdGgganVzdCBvbmUgZmFjdWx0eSBtZW1iZXIuCgpgYGB7ciwgZWNobz1GQUxTRX0KcGxvdF9seShmb3Jfc3VtLHdpZHRoPTEwMDAsCiAgICAgICAgIGhlaWdodCA9IDUwMCkgJT4lIAogIGFkZF90cmFjZSh4ID0gfnNjaG9vbF9maW5hbCx5PX5uX3VybHMsdHlwZT0nYmFyJyxuYW1lID0gJ1RvdGFsIE51bWJlcicsCiAgICAgICAgICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwKICAgICAgICAgICAgdGV4dCA9IH5wYXN0ZShzY2hvb2xfZmluYWwsICc6ICcsbl91cmxzLCcgdG90YWwgc2l0ZXMgd2l0aCB2aWRlbycsc2VwPSIiKSx4YXhpcz0iU2Nob29sIikgJT4lIAogIGFkZF90cmFjZSh4ID0gfnNjaG9vbF9maW5hbCwgeT1+bl9oeXBlcix0eXBlPSdiYXInLG5hbWU9J051bWJlciB3aXRoIEh5cGVybGlua3MnLAogICAgICAgICAgICBob3ZlcmluZm8gPSAidGV4dCIsCiAgICAgICAgICAgIHRleHQgPSB+cGFzdGUoc2Nob29sX2ZpbmFsLCAnOiAnLG5faHlwZXIsJyBzaXRlcyB3aXRoIGh5cGVybGlua3MnLHNlcD0iIikpICU+JSAKICBhZGRfdHJhY2UoeD1+c2Nob29sX2ZpbmFsLCB5PX5uX2VtYmVkLHR5cGU9J2JhcicsbmFtZT0nTnVtYmVyIHdpdGggRW1iZWRzJywKICAgICAgICAgICAgaG92ZXJpbmZvID0gInRleHQiLAogICAgICAgICAgICB0ZXh0ID0gfnBhc3RlKHNjaG9vbF9maW5hbCwgJzogJyxuX2VtYmVkLCcgc2l0ZXMgd2l0aCBlbWJlZHMnLHNlcD0iIikpICU+JSAKICBsYXlvdXQoeGF4aXMgPSB4LAogICAgICAgICB5YXhpcyA9IHkyLAogICAgICAgICBhdXRvc2l6ZSA9IEYpCgoKIyBwbG90X2x5KGZvcl9zdW0seD1+c2Nob29sX2ZpbmFsLHk9fm5fdXJscyx0eXBlPSJiYXIiLGhvdmVydGV4dD1wYXN0ZSgiUGVyY2VudDoiLCBmb3JtYXQocm91bmQoZm9yX3N1bSRtZWFuLCAyKSwgbnNtYWxsID0gMikpLHhheGlzPSJTY2hvb2wiKSU+JSAKIyAgIGxheW91dCh4YXhpcz14LHlheGlzPXkyKQpgYGAKCi0tLQoKIyNOdW1iZXIgb2YgV2Vic2l0ZXMgd2l0aCBWaWRlb3MgKFRhYmxlKQoKYGBge3IsIGVjaG89RkFMU0V9CiNudW1iZXIgb2Ygc2l0ZXMgdGFibGUKZGlzcGxheV9mb3Jfc3VtIDwtIGZvcl9zdW1bLGMoMSwzLDUsNyldCm5hbWVzKGRpc3BsYXlfZm9yX3N1bSkgPC0gYygiU2Nob29sIiwgIlRvdGFsIE51bWJlciBvZiBTaXRlcyB3aXRoIFZpZGVvcyIsICJOdW1iZXIgd2l0aCBIeXBlcmxpbmtzIiwgIk51bWJlciB3aXRoIEVtYmVkcyIpCmthYmxlKGRpc3BsYXlfZm9yX3N1bSkgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIpLGZ1bGxfd2lkdGggPSBGLHBvc2l0aW9uPSJjZW50ZXIiKSAlPiUgCiAgZm9vdG5vdGUoZ2VuZXJhbD0iU29tZSBzaXRlcyBtYXkgaGF2ZSBib3RoIGh5cGVybGlua3MgQU5EIGVtYmVkZGVkIHZpZGVvLCBzbyB0aGUgc3VtIG9mIHRoZSBsYXN0IDIgY29sdW1ucyBtYXkgYmUgZ3JlYXRlciB0aGFuIHRoZSBmaXJzdC4iKQogIApgYGAKCi0tLQoKI0xpbWl0YXRpb25zIGFuZCBsb29raW5nIGZvcndhcmQKCiMjIyNVbmRlciBjb3VudGluZwotIFdoZW4gbG9va2luZyBmb3IgaHlwZXJsaW5rZWQgdmlkZW9zLCB3ZSBvbmx5IGxvb2tlZCBmb3IgbGlua3MgdG8gWW91VHViZS5jb20gYW5kIFZpbWVvLmNvbS4gVGhpcyBkZWNpc2lvbiB3YXMgbWFkZSBhZnRlciBzZWVpbmcgdGhhdCB0aGVzZSB3ZXJlIHRoZSBzb3VyY2VzIG9mIHRoZSBtYWpvcml0eSBvZiB0aGUgZW1iZWRkZWQgdmlkZW9zLiBBbHRob3VnaCB0aGVzZSBhcmUgdGhlIHR3byBsZWFkaW5nIHZpZGVvIHBsYXRmb3JtcyBub3QganVzdCBhdCBIYXJ2YXJkLCBidXQgb24gdGhlIGludGVybmV0IGluIGdlbmVyYWwsIGl0IGlzIHBvc3NpYmxlIHRoYXQgc29tZSBmYWN1bHR5IG1lbWJlcnMgbWF5IGhhdmUgbGlua3MgdG8gdmlkZW9zIGhvc3RlZCBvbiBvdGhlciwgbGVzc2VyIGtub3duIHdlYnNpdGVzLgoKLSBJdCBpcyBwb3NzaWJsZSB0aGF0IHdlIGhhdmUgdW5kZXItY291bnRlZCB2aWRlb3MgZnJvbSB0aGUgSGFydmFyZCBNZWRpY2FsIFNjaG9vbC4gSE1TIGZhY3VsdHkgdXNlIHRoZSBbSGFydmFyZCBDYXRhbHlzdF0oaHR0cHM6Ly9jYXRhbHlzdC5oYXJ2YXJkLmVkdS8pIHBsYXRmb3JtIHRvIGNyZWF0ZSB0aGVpciB3ZWJzaXRlcy4gQXMgZmFyIGFzIHdlIGhhdmUgYmVlbiBhYmxlIHRvIGFzY2VydGFpbiwgdGhpcyBwbGF0Zm9ybSBkb2VzIG5vdCBhbGxvdyBmYWN1bHR5IG1lbWJlcnMgdG8gcG9zdCB2aWRlb3MuIElmIHRoaXMgZnVuY3Rpb25hbGl0eSBkb2VzIGluIGZhY3QgZXhpc3QsIG9yIGlmIEhNUyBmYWN1bHR5IG1lbWJlcnMgaGF2ZSB3ZWJzaXRlcyB3ZSB3ZXJlIG5vdCBhYmxlIHRvIGNvbGxlY3QsIG91ciB0b3RhbCBjb3VudCBtYXkgYmUgb2ZmLgoKLSBPdXIgZGF0YWJhc2Ugb2YgZnFhY3VsdHkgd2Vic2l0ZXMgbWF5IG5vdCBiZSBjb21wcmVoZW5zaXZlIC0gZmFjdWx0eSBtZW1iZXJzIG1heSBoYXZlIHdlYnNpdGVzIHdlIGRvIG5vdCBrbm93IG9mLiBBcyB0aGUgTElOSyBwcm9qZWN0IHByb2dyZXNzZXMsIG91ciBkYXRhYmFzZSBvZiBmYWN1bHR5IHdlYnNpdGVzIHdpbGwgaW1wcm92ZS4KCi0gVGhlcmUgd2VyZSBhdCBsZWFzdCB0d28gY2FzZXMgd2hlcmUgd2UgbG9zdCBsZWdpdGltYXRlIGRhdGEgd2hlbiBtZXJnaW5nIHRoZSBzY3JhcGVkIGRhdGEgc2V0IGFuZCB0aGUgYmlvZ3JhcGhpY2FsIGRhdGEgc2V0LiBUaGlzIHdhcyBiZWNhdXNlIHNvbWVvbmUgZWxzZSAocG9zc2libHkgYW4gYXNzaXN0YW50KSBoYWQgc2V0IHVwIGFuIE9wZW5TY2hvbGFyIHNpdGUgZm9yIGEgZmFjdWx0eSBtZW1iZXIgdXNpbmcgdGhlaXIgb3duIEhVSUQsIHJhdGhlciB0aGFuIHRoZSBmYWN1bHR5IG1lbWJlcidzLiBXaGlsZSB3ZSBiZWxpZXZlIHdlIGNhdWdodCBhbGwgaW5zdGFuY2VzIG9mIHRoaXMgKDIpLCBpdCBpcyBwb3NzaWJsZSB3ZSBtaXNzZWQgbW9yZS4KCiMjIyNMb29raW5nIGZvcndhcmQKCldlIGFyZSBjdXJyZW50bHkgaW4gdGhlIHByb2Nlc3Mgb2YgY3Jhd2xpbmcsIHNjcmFwaW5nLCBhbmQgYW5hbHl6aW5nIGRlcGFydG1lbnQgYW5kIG9yZ2FuaXphdGlvbiB3ZWJzaXRlcy4gT25jZSB0aGF0IGRhdGEgaXMgcHJvY2Vzc2VkLCB3ZSB3aWxsIGdlbmVyYXRlIGFub3RoZXIgcmVwb3J0LgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CndyaXRlLmNzdih3aXRoX3NjaG9vbCwid2l0aF9zY2hvb2wuY3N2IikKYGBgCgo=